import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import protocol.print.PrintRequestReceived;
import protocol.registration.PrinterRegistrationRequest;
import protocol.registration.PrinterRegistrationResponse;
import protocol.registration.TypeRequestResponse;

import helpers.Client;

public class TCPClientServer extends Thread {

	public Client client;

	public int port;

	public ServerSocket serverSocketClient;
	public ArrayList<Integer> printers;
	public TCPServer tcpServer;
	public static PrintRequestReceived prrec = null;
	public int trrp = 0;

	public TCPClientServer(int port, Client client, TCPServer tcpServer) {
		this.port = port;
		this.client = client;
		this.tcpServer = tcpServer;
		printers = new ArrayList<Integer>();
	}

	@Override
	public void run() {
		try {

			this.serverSocketClient = new ServerSocket(port);
		} catch (Exception e) {

			System.err.println("Exceptie la crearea ServerSocket-ului: " + e);
			e.printStackTrace();
			return;
		}

		System.out.println("[TCPServer] Accepting a new connection");

		Socket clientSocket = null;

		try {

			clientSocket = this.serverSocketClient.accept();
		} catch (Exception e) {

			System.err.println("Eroare la accept: " + e);
			e.printStackTrace();
		}
		// Primeste mesaj de la Client si trimite ACK
		try {

			while (true) {

				if (prrec != null && client.getType().equals("Printer")) {
					System.out.println("Am trimis la printat");
					prrec.write(new DataOutputStream(clientSocket
							.getOutputStream()));
					prrec = null;
				}
				if (client.getType().equals("Client")) {
					TypeRequestResponse trr = new TypeRequestResponse();
					trr.read(new DataInputStream(clientSocket.getInputStream()));

					trrp = trr.tipRequest;

					switch (trrp) {
					// printare
					case 0:
						// Am primit cerere de printare
						PrintRequestReceived prr = new PrintRequestReceived();
						prr.read(new DataInputStream(clientSocket
								.getInputStream()));

						// Trimit cererea la imprimanta
						if (tcpServer.m_printers.containsKey(client.getId())) {
							int printerID = tcpServer.m_printers.get(client
									.getId());

							for (int i = 0; i < tcpServer.m_thClients.size(); i++) {
								TCPClientServer t = tcpServer.m_thClients
										.get(i);

								if (t.client.getId() == printerID) {
									System.out.println("Am gasit imprimanta");
									t.printThis(prr);
									this.join();
								}
							}
						}

						break;

					case 1:
						// printer Registration
						PrinterRegistrationRequest preg = new PrinterRegistrationRequest();
						preg.read(new DataInputStream(clientSocket
								.getInputStream()));

						tcpServer.m_printers.put(preg.getClientID(),
								preg.getPrinterID());

						PrinterRegistrationResponse presp = new PrinterRegistrationResponse(
								true);
						presp.write(new DataOutputStream(clientSocket
								.getOutputStream()));
						break;
					}

				}
			}
			// procesez taskuri

		} catch (Exception e) {

			System.err.println("Eroare la raspuns Server-Client: " + e);
			e.printStackTrace();
		} finally {
			try {
				clientSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		try {

			this.serverSocketClient.close();
		} catch (Exception e) {

			System.err.println("ServerSocket close exception: " + e);
			e.printStackTrace();
		}
	}

	public synchronized void printThis(PrintRequestReceived prr) {
		prrec = prr;
	}
}
